﻿using Cognitum.CassandraProviders.Cassandra;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Configuration.Provider;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cognitum.ProvidersTests
{
    [TestFixture]
    internal class RoleProviderTests : BaseProvidersTest
    {
        #region Methods

        [Test]
        public void AddUsersToRoles_RoleNotExist()
        {
            // Arrange
            string[] users = { _userName };
            string[] roles = { _roleWriter };
            // Act
            // Assert
            Assert.Throws(
                typeof(ProviderException),
                delegate { _providerRole.AddUsersToRoles(users, roles); });
        }

        [Test]
        public void AddUsersToRoles_ThreeUsersOneRoles()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            string[] users = { _userName, "userdName" };
            string[] roles = { _roleWriter };
            // Act
            _providerRole.AddUsersToRoles(users, roles);
            bool result = _providerRole.IsUserInRole(_userName, _roleWriter);
            bool result2 = _providerRole.IsUserInRole("userdName", _roleWriter);
            bool result3 = _providerRole.IsUserInRole("userdName2", _roleWriter);
            // Assert
            Assert.IsTrue(result);
            Assert.IsTrue(result2);
            Assert.IsFalse(result3);
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
        }

        [Test]
        public void CreateRole_ExistOnDatabase()
        {
            // Arrange
            // Act
            _providerRole.CreateRole(_roleReader);
            // Assert
            Assert.Throws(typeof(ProviderException),
                delegate { _providerRole.CreateRole(_roleReader); });
            //Clean
            _providerRole.DeleteRole(_roleReader, false);
        }

        [Test]
        public void CreateRole_HappyPath()
        {
            string[] result2 = _providerRole.GetAllRoles();
            // Arrange
            // Act
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole(_roleWriter);
            string[] result = _providerRole.GetAllRoles();
            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result2.Count() + 2, result.Count());
            //Clean
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
        }

        [Test]
        public void DeleteRole_HappyPath()
        {
            string[] result3 = _providerRole.GetAllRoles();
            // Arrange
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole(_roleWriter);
            string[] result = _providerRole.GetAllRoles();
            // Act
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            string[] result2 = _providerRole.GetAllRoles();
            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result3.Count() + 2, result.Count());
            Assert.IsNotNull(result2);
            Assert.AreEqual(result3.Count(), result2.Count());
        }

        [Test]
        public void DeleteRole_NotExist()
        {
            // Arrange
            // Act
            // Assert
            Assert.Throws(typeof(ProviderException),
                delegate { _providerRole.DeleteRole(_roleWriter, false); });
        }

        [Test]
        public void DeleteRole_PopulatedRoleIsTrue_NotThrowException()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            // Act
            bool result = _providerRole.IsUserInRole(_userName, _roleWriter);
            bool result2 = _providerRole.IsUserInRole("userdName", _roleWriter);
            bool result3 = _providerRole.DeleteRole(_roleWriter, true);
            // Assert
            Assert.IsFalse(result);
            Assert.IsFalse(result2);
            Assert.IsTrue(result3);
        }

        [Test]
        public void DeleteRole_PopulatedRoleIsTrue_ThrowException()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            string[] users = { _userName, "userdName" };
            string[] roles = { _roleWriter };
            // Act
            _providerRole.AddUsersToRoles(users, roles);
            bool result = _providerRole.IsUserInRole(_userName, _roleWriter);
            bool result2 = _providerRole.IsUserInRole("userdName", _roleWriter);
            bool result3 = _providerRole.IsUserInRole("userdName2", _roleWriter);
            // Assert
            Assert.IsTrue(result);
            Assert.IsTrue(result2);
            Assert.IsFalse(result3);
            Assert.Throws(
                typeof(ProviderException),
                delegate { _providerRole.DeleteRole(_roleWriter, true); });
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
        }

        [Test]
        public void FindUsersInRole_EmptyDatabase()
        {
            // Arrange
            string[] users = new string[] { _userName, "userdName", "userdName2" };
            string[] roles = new string[] { _roleReader, _roleWriter };
            // Act
            string[] result3 = _providerRole.FindUsersInRole(_roleWriter, "us");
            // Assert
            Assert.IsEmpty(result3);
        }

        [Test]
        public void FindUsersInRole_HappyPath()
        {
            string[] result4 = _providerRole.FindUsersInRole(_roleWriter, "us");
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { _userName, "userdName", "userdName2" };
            string[] roles = new string[] { _roleReader, _roleWriter };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            bool result = _providerRole.IsUserInRole(_userName, _roleReader);
            bool result2 = _providerRole.IsUserInRole(_userName, _roleWriter);
            string[] result3 = _providerRole.FindUsersInRole(_roleWriter, "us");
            // Assert
            Assert.IsTrue(result);
            Assert.IsTrue(result2);
            Assert.IsNotNull(result3);
            Assert.AreEqual(result4.Count() + 2, result3.Count());
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void GetAllRoles_HappyPath()
        {
            string[] result2 = _providerRole.GetAllRoles();
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            string[] users = { _userName, "userdName" };
            string[] roles = { _roleWriter };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            string[] result = _providerRole.GetAllRoles();
            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result2.Count() + 2, result.Count());
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
        }

        [Test]
        public void GetRolesForUser_HappyPath()
        {
            string[] result2 = _providerRole.GetRolesForUser(_userName);
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            string[] users = { _userName, "userdName" };
            string[] roles = { _roleWriter, _roleReader };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            string[] result = _providerRole.GetRolesForUser(_userName);
            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(result2.Count() + 2, result.Count());
            Assert.IsTrue(result.Contains(_roleReader));
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
        }

        [Test]
        public void GetRolesForUser_NotRoles()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            string[] users = { _userName, "userdName" };
            string[] roles = { };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            string[] result = _providerRole.GetRolesForUser(_userName);
            // Assert
            Assert.IsNotNull(result);
            Assert.IsEmpty(result);
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
        }

        [Test]
        public void GetRolesForUser_NotUsers()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            string[] users = { };
            string[] roles = { _roleWriter, _roleReader };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            string[] result = _providerRole.GetRolesForUser(_userName);
            // Assert
            Assert.IsNotNull(result);
            Assert.IsEmpty(result);
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
        }

        [Test]
        public void GetUsersInRole_HappyPath()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { _userName };
            string[] roles = new string[] { _roleReader, _roleWriter };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            string[] result = _providerRole.GetUsersInRole(_roleWriter);
            // Assert
            Assert.IsNotNull(result);
            Assert.True(result.Contains(_userName));
            //Clean

            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void IsUserInRole_EmptyRoles()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { _userName };
            string[] roles = new string[] { };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            bool result = _providerRole.IsUserInRole(_userName, _roleReader);
            bool result2 = _providerRole.IsUserInRole(_userName, _roleWriter);
            bool result3 = _providerRole.IsUserInRole(_userName, "test");
            // Assert
            // Assert
            Assert.IsFalse(result);
            Assert.IsFalse(result2);
            Assert.IsFalse(result3);
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void IsUserInRole_EmptyUsers()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { };
            string[] roles = new string[] { _roleReader, _roleWriter };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            bool result = _providerRole.IsUserInRole(_userName, _roleReader);
            bool result2 = _providerRole.IsUserInRole(_userName, _roleWriter);
            bool result3 = _providerRole.IsUserInRole(_userName, "test");
            // Assert
            // Assert
            Assert.IsFalse(result);
            Assert.IsFalse(result2);
            Assert.IsFalse(result3);
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void IsUserInRole_HappyPath()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { _userName };
            string[] roles = new string[] { _roleReader, _roleWriter };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            bool result = _providerRole.IsUserInRole(_userName, _roleReader);
            bool result2 = _providerRole.IsUserInRole(_userName, _roleWriter);
            bool result3 = _providerRole.IsUserInRole(_userName, "test");
            // Assert
            // Assert
            Assert.IsTrue(result);
            Assert.IsTrue(result2);
            Assert.IsFalse(result3);
            //Clean
            _providerRole.RemoveUsersFromRoles(users, roles);
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void RemoveUsersFromRoles_EmptyRoles()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { _userName };
            string[] roles = new string[] { };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            _providerRole.RemoveUsersFromRoles(users, roles);
            bool result = _providerRole.IsUserInRole(_userName, _roleReader);
            bool result2 = _providerRole.IsUserInRole(_userName, _roleWriter);
            // Assert
            Assert.IsFalse(result);
            Assert.IsFalse(result2);
            //Clean
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void RemoveUsersFromRoles_EmptyUsers()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { };
            string[] roles = new string[] { _roleReader, _roleWriter };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            _providerRole.RemoveUsersFromRoles(users, roles);
            bool result = _providerRole.IsUserInRole(_userName, _roleReader);
            bool result2 = _providerRole.IsUserInRole(_userName, _roleWriter);
            // Assert
            Assert.IsFalse(result);
            Assert.IsFalse(result2);
            //Clean
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void RemoveUsersFromRoles_HappyPath()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            _providerRole.CreateRole(_roleReader);
            _providerRole.CreateRole("test");
            string[] users = new string[] { _userName };
            string[] roles = new string[] { _roleReader, _roleWriter };
            _providerRole.AddUsersToRoles(users, roles);
            // Act
            _providerRole.RemoveUsersFromRoles(users, roles);
            bool result = _providerRole.IsUserInRole(_userName, _roleReader);
            bool result2 = _providerRole.IsUserInRole(_userName, _roleWriter);
            // Assert
            Assert.IsFalse(result);
            Assert.IsFalse(result2);
            //Clean
            _providerRole.DeleteRole(_roleWriter, false);
            _providerRole.DeleteRole(_roleReader, false);
            _providerRole.DeleteRole("test", false);
        }

        [Test]
        public void RoleExists_Exist()
        {
            // Arrange
            _providerRole.CreateRole(_roleWriter);
            // Act
            bool result = _providerRole.RoleExists(_roleWriter);
            // Assert
            Assert.IsTrue(result);
            //Clean
            _providerRole.DeleteRole(_roleWriter, false);
        }

        [Test]
        public void RoleExists_NotExist()
        {
            // Arrange
            // Act
            bool result = _providerRole.RoleExists(_roleWriter);
            // Assert
            Assert.IsFalse(result);
            //Clean
        }

        #endregion Methods
    }
}